<template>
  <div>
    <UploadDragger
      ref="dragger"
      name="file"
      :multiple="true"
      :directory="true"
      :custom-request="handleCustomRequest"
      :file-list="fileList"
      :show-upload-list="true"
      :before-upload="beforeUpload"
      @change="handleChange"
    >
      <p class="ant-upload-drag-icon">
        <a-icon type="inbox" />
      </p>
      <p class="ant-upload-text">点击或拖拽上传文件或文件夹</p>
      <p class="ant-upload-hint">
        支持多文件上传，每个文件不超过 <strong>50MB</strong>，总大小不超过 <strong>500MB</strong>。
      </p>
    </UploadDragger>
  </div>
</template>

<script lang="ts" setup>
  import { ref } from 'vue';
  import { Upload } from 'ant-design-vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { uploadFileApi } from '/@/api/sys/upload';

  const UploadDragger = Upload.UploadDragger;
  const { createMessage } = useMessage();
  const fileList = ref<any[]>([]);
  const dragger = ref<HTMLElement | null>(null);

  // 配置参数
  const maxSingleSize = 50; // 单文件最大 50MB
  const maxTotalSize = 500; // 总文件最大 500MB
  const maxFileCount = 10; // 最多 10 个文件

  // 上传前校验
  const beforeUpload = (file: File) => {
    // 数量限制
    if (fileList.value.length >= maxFileCount) {
      createMessage.warning(`最多只能上传 ${maxFileCount} 个文件`);
      return false;
    }

    // 单文件大小限制
    if (file.size / 1024 / 1024 > maxSingleSize) {
      createMessage.error(`文件 ${file.name} 超过单文件大小限制 ${maxSingleSize}MB`);
      return false;
    }

    // 总大小限制
    const totalSizeMB =
      fileList.value.reduce((sum, f) => sum + (f.size || 0), 0) / 1024 / 1024 +
      file.size / 1024 / 1024;

    if (totalSizeMB > maxTotalSize) {
      createMessage.error(`上传文件总大小不能超过 ${maxTotalSize}MB`);
      return false;
    }

    // 重复文件名校验
    const isDuplicate = fileList.value.some((f) => f.name === file.name);
    if (isDuplicate) {
      createMessage.warning(`已存在文件名为 ${file.name} 的文件`);
      return false;
    }

    return true;
  };

  // 自定义上传方法
  const handleCustomRequest = async ({ file, onProgress, onSuccess, onError }: any) => {
    try {
      const res = await uploadFileApi(
        {
          file: file as File,
          filename: 'file',
        },
        {
          onUploadProgress: (progressEvent: ProgressEvent) => {
            const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
            if (onProgress) {
              onProgress({ percent } as any);
            }
          },
        },
      );

      file.status = 'done';
      file.response = res;
      onSuccess && onSuccess(res, file);
      createMessage.success(`上传成功：${(file as File).name}`);
    } catch (err) {
      file.status = 'error';
      onError && onError(err);
      createMessage.error(`上传失败：${(file as File).name}`);
    }
  };

  // 更新 fileList
  const handleChange = (info: any) => {
    fileList.value = info.fileList;
    console.log(fileList.value);
  };
</script>

<style scoped lang="less">
  .ant-upload-hint {
    margin-top: 8px;
    font-size: 13px;
    color: #999;
  }
</style>
